package com.chookss.wxapi;


import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.chookss.tools.GlideUtils;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.zxy.tiny.Tiny;
import com.zxy.tiny.callback.FileCallback;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class WeChatShareUtil {

    //从官网申请的合法appId
    private static final int TIMELINE_SUPPORTED_VERSION = 0x21020001;
    //IWXAPI是第三方app和微信通信的openapi接口
    private IWXAPI api;
    private Context context;
    public static WeChatShareUtil weChatShareUtil;

    public static WeChatShareUtil getInstance(Context context) {
        if (weChatShareUtil == null) {
            weChatShareUtil = new WeChatShareUtil();
        }
        if (weChatShareUtil.api != null) {
            weChatShareUtil.api.unregisterApp();
        }
        weChatShareUtil.context = context;
        weChatShareUtil.regToWx();
        return weChatShareUtil;
    }

    //注册应用id到微信
    private void regToWx() {
        //通过WXAPIFactory工厂，获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(context, ShareConstants.WX_APP_KEY, true);
        //将应用的appId注册到微信
        api.registerApp(ShareConstants.WX_APP_KEY);
    }

    /**
     * 分享文字到朋友圈或者好友
     *
     * @param text  文本内容
     * @param scene 分享方式：好友还是朋友圈
     */
    public boolean shareText(String text, int scene) {
        //初始化一个WXTextObject对象，填写分享的文本对象
        WXTextObject textObj = new WXTextObject();
        textObj.text = text;
        return share(textObj, text, scene);
    }

    /**
     * 分享图片到朋友圈或者好友
     *
     * @param bmp   图片的Bitmap对象
     * @param scene 分享方式：好友还是朋友圈
     */
    public boolean sharePic(Bitmap bmp, int scene) {
        //初始化一个WXImageObject对象
        WXImageObject imageObj = new WXImageObject(bmp);
        //设置缩略图
        Bitmap thumb = Bitmap.createScaledBitmap(bmp, 60, 60, true);
        bmp.recycle();
        return share(imageObj, thumb, scene);
    }

    /**
     * 分享网页到朋友圈或者好友，视频和音乐的分享和网页大同小异，只是创建的对象不同。
     * 详情参考官方文档：
     * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317340&token=&lang=zh_CN
     *
     * @param url         网页的url
     * @param title       显示分享网页的标题
     * @param description 对网页的描述
     * @param scene       分享方式：好友还是朋友圈
     */
    public boolean shareUrl(String url, String title, Bitmap thumb, String description, int scene) {
        //初试话一个WXWebpageObject对象，填写url
        WXWebpageObject webPage = new WXWebpageObject();
        webPage.webpageUrl = url;
        return share(webPage, title, thumb, description, scene);
    }

    private boolean share(WXMediaMessage.IMediaObject mediaObject, Bitmap thumb, int scene) {
        return share(mediaObject, null, thumb, null, scene);
    }

    private boolean share(WXMediaMessage.IMediaObject mediaObject, String description, int scene) {
        return share(mediaObject, null, null, description, scene);
    }

    private boolean share(WXMediaMessage.IMediaObject mediaObject, String title, Bitmap thumb, String description, int scene) {
        //初始化一个WXMediaMessage对象，填写标题、描述
        WXMediaMessage msg = new WXMediaMessage(mediaObject);
        if (title != null) {
            msg.title = title;
        }
        if (description != null) {
            msg.description = description;
        }
        if (thumb == null) {
            thumb = BitmapFactory.decodeResource(context.getResources(), GlideUtils.loadPushId(context));
        }
        Bitmap thumbBmp = Bitmap.createScaledBitmap(thumb, 150, 150, true);
//        thumb.recycle();
        msg.thumbData = bmpToByteArray(thumbBmp, true);
        //构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.message = msg;
        req.scene = scene;
        return api.sendReq(req);
    }

    /**
     * 分享图片
     *
     * @param imgurl 保存图片路径
     */
    public void imageShare(String imgurl, String mimeType, int size) {
        if (size > (900)) {
            toCompress(imgurl, mimeType, size);
            return;
        }
        Bitmap bmp = BitmapFactory.decodeFile(imgurl);
        if (Build.VERSION.SDK_INT >= 30) {
            bitmapSaveFile(context, bmp, mimeType)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<File>() {
                        @Override
                        public void accept(File file) throws Exception {
                            String contentPath = getFileUri(context, file);
                            WXImageObject imageObject = new WXImageObject();
                            imageObject.setImagePath(contentPath);
                            WXMediaMessage msg = new WXMediaMessage(imageObject);
                            // 设置缩略图
                            Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 150, 150, true);
                            bmp.recycle();
                            msg.thumbData = bmpToByteArray(thumbBmp, true);

                            //构建一个Req
                            SendMessageToWX.Req req = new SendMessageToWX.Req();
                            req.transaction = "img";

                            req.message = msg;
                            req.scene = 0;
                            api.sendReq(req);
                        }
                    });
        } else {
            WXImageObject imgObj = new WXImageObject();
            imgObj.setImagePath(imgurl);
            WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = imgObj;

            Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 150, 150, true);
            msg.setThumbImage(thumbBmp);
            bmp.recycle();
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = String.valueOf(System.currentTimeMillis());
            req.message = msg;
            req.scene = 0;
            api.sendReq(req);
        }

    }

    private void toCompress(String imgurl, String mimeType, int size) {
        Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
        options.quality = 95;
        options.size = 1024 * 100;
        Tiny.getInstance().source(new File(imgurl)).asFile().withOptions(options).compress(new FileCallback() {
            @Override
            public void callback(boolean isSuccess, String outfile, Throwable t) {
                if (isSuccess) {
                    String url = outfile;
                    if (url.contains(".")) {
                        String[] nums = url.split("\\.");
                        imageShare(url, nums[nums.length - 1], 900);
                    } else {
                        imageShare(url, mimeType, 900);
                    }

                } else {
                    imageShare(imgurl, mimeType, 900);
                }
            }
        });
    }

    /**
     * 注意，先清空文件夹文件
     *
     * @return
     */
    public static Observable<File> bitmapSaveFile(@NonNull final Context context,
                                                  @NonNull final Bitmap bitmap, final String mimeType) {
        return Observable.create(new ObservableOnSubscribe<File>() {
            @Override
            public void subscribe(ObservableEmitter<File> emitter) throws Exception {
                OutputStream outputStream = null;
                try {
                    String fileName = "img_" + System.currentTimeMillis() + "." + mimeType;
                    final File screenshotsDir = new File(context.getExternalFilesDir(null), "shareData");

                    if (!screenshotsDir.exists()) { //如果该文件夹不存在，则进行创建
                        screenshotsDir.mkdirs();//创建文件夹
                    } else {
                        for (File file : screenshotsDir.listFiles()) {
                            if (file.isFile()) {
                                file.delete(); // 删除所有文件
                            }
                        }
                    }
                    File screenshotFile = new File(screenshotsDir, fileName);
                    outputStream = new BufferedOutputStream(new FileOutputStream(screenshotFile));
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                    outputStream.flush();
                    emitter.onNext(screenshotFile);
                    emitter.onComplete();
                } catch (final IOException e) {
                    emitter.onError(e);
                } finally {
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (final IOException ignored) {
                        }
                    }
                }
            }

        }).subscribeOn(Schedulers.io());
    }


    public String getFileUri(Context context, File file) {
        if (file == null || !file.exists()) {
            return null;
        }

        Uri contentUri = FileProvider.getUriForFile(context,
                context.getPackageName() + ".wechatShare",  // 要与`AndroidManifest.xml`里配置的`authorities`一致，假设你的应用包名为com.example.app
                file);

        // 授权给微信访问路径
        context.grantUriPermission("com.tencent.mm",  // 这里填微信包名
                contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

        return contentUri.toString();   // contentUri.toString() 即是以"content://"开头的用于共享的路径
    }

    //判断是否支持转发到朋友圈
    //微信4.2以上支持，如果需要检查微信版本支持API的情况， 可调用IWXAPI的getWXAppSupportAPI方法,0x21020001及以上支持发送朋友圈
    public boolean isSupportWX() {
        int wxSdkVersion = api.getWXAppSupportAPI();
        return wxSdkVersion >= TIMELINE_SUPPORTED_VERSION;
    }

    private byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

}
